package com.region.http.client.common;

import com.region.http.client.annotation.request.*;
import com.region.http.client.model.RequestMeta.RequestMetaBuilder;

import java.lang.annotation.Annotation;

/**
 * The Request Type
 *
 * @author liujieyu
 * @date 2023/6/10 16:36
 * @desciption
 */
public enum RequestType {
    GET {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) {
            GetUrl url = (GetUrl) annotation;
            return builder.requestType(RequestType.GET)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    POST {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            PostUrl url = (PostUrl) annotation;
            return builder.requestType(RequestType.POST)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    PUT {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            PutUrl url = (PutUrl) annotation;
            return builder.requestType(RequestType.PUT)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    DELETE {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            DeleteUrl url = (DeleteUrl) annotation;
            return builder.requestType(RequestType.DELETE)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    HEAD {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            HeadUrl url = (HeadUrl) annotation;
            return builder.requestType(RequestType.HEAD)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    OPTIONS {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            OptionsUrl url = (OptionsUrl) annotation;
            return builder.requestType(RequestType.OPTIONS)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    },
    TRACE {
        @Override
        public RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException {
            TraceUrl url = (TraceUrl) annotation;
            return builder.requestType(RequestType.TRACE)
                    .connectTime(url.connectTime())
                    .requestTime(url.requestTime())
                    .contentType(url.contentType())
                    .executor(url.executor())
                    .readTime(url.readTime())
                    .originUrl(url.value());
        }
    };

    /**
     * Get request meta data
     *
     * @return
     * @throws UnsupportedOperationException
     */
    public abstract RequestMetaBuilder getMeta(RequestMetaBuilder builder, Annotation annotation) throws UnsupportedOperationException;

    /**
     * Parse and initialize the annotation as RequestMeta.RequestMetaBuilder
     *
     * @param annotation
     * @return
     */
    public static RequestMetaBuilder parseAnnotation(RequestMetaBuilder builder, Annotation annotation) {
        if (annotation instanceof GetUrl) {
            return RequestType.GET.getMeta(builder, annotation);
        }
        if (annotation instanceof PostUrl) {
            return RequestType.POST.getMeta(builder, annotation);
        }
        if (annotation instanceof DeleteUrl) {
            return RequestType.DELETE.getMeta(builder, annotation);
        }
        if (annotation instanceof HeadUrl) {
            return RequestType.HEAD.getMeta(builder, annotation);
        }
        if (annotation instanceof OptionsUrl) {
            return RequestType.OPTIONS.getMeta(builder, annotation);
        }
        if (annotation instanceof PutUrl) {
            return RequestType.PUT.getMeta(builder, annotation);
        }
        if (annotation instanceof TraceUrl) {
            return RequestType.TRACE.getMeta(builder, annotation);
        }
        return builder;
    }

}
